package iotdbdemo

import (
	"fmt"
	"math"
	"math/rand"
	"sync"
	"time"
)

type DataTest struct {
	Thread             int //线程数
	DataLen            int //数据量
	MaxOneTimeDealData int
	PoolSize           int
	Host               string
}

// AddDataTest NewCar 是 Car 的构造函数
func AddDataTest(thread, len, maxOneTimeDealData, poolSize int, host string) *DataTest {
	return &DataTest{
		Thread:             thread,
		DataLen:            len,
		MaxOneTimeDealData: maxOneTimeDealData,
		PoolSize:           poolSize,
		Host:               host,
	}
}

// Run Display 为 Car 类定义一个方法，用来显示汽车的信息
func (c *DataTest) Run() {
	fmt.Printf("run DataTest: %d thread , %d data, deal %d data for one time.\n", c.Thread, c.DataLen, c.MaxOneTimeDealData)
	// 计算每个线程应该处理的数据长度
	ContactDataBase(c.PoolSize, c.Host)
	lengthPerThread := int(math.Ceil(float64(c.DataLen) / float64(c.Thread)))
	var wg sync.WaitGroup
	start := 0
	for i := 0; i < c.Thread; i++ {
		end := start + lengthPerThread
		if end > c.DataLen {
			end = c.DataLen
		}

		wg.Add(1)
		go processData(i, start, end, c.MaxOneTimeDealData, &wg)

		start += lengthPerThread
		if start >= c.DataLen {
			break
		}
	}
	wg.Wait()
	fmt.Println("All data processed.")
}

func processData(thred, start, end, maxOneTimeDealData int, wg *sync.WaitGroup) {
	defer wg.Done()
	//length := end - start
	fmt.Printf("thred %d Processing data from %d to %d ,maxOneTimeDealData %d\n", thred, start, end, maxOneTimeDealData)
	maxCount := (end - start) / maxOneTimeDealData
	count := 0
	for {
		now := time.Now()
		count++
		randomDev := generateRandomString()
		fmt.Printf("[2%d:2%d:2%d] Th %4d  p dev: %16s ,c: %4d ->  %4d data: %10d->%10d  \n", now.Hour(), now.Minute(), now.Second(), thred, randomDev, count, maxCount, start, end)
		if start+maxOneTimeDealData < end {
			//fmt.Printf("  1.inner processing data start %d , end %d\n", start, start+maxOneTimeDealData)
			start += maxOneTimeDealData
			timestamp, _ := randomTimestampInRange("20230101 00:00:00", "20240101 00:00:00")
			// 随机一次生成 【maxOneTimeDealData】个2023年数据，并批量插入到时序数据库内
			BatchInsertTestDataToDB(maxOneTimeDealData, timestamp, randomDev)
		} else {
			length := end - start
			start += length
			fmt.Printf("Thred %d p dev: %s , data: %d->%d  count %d -> maxCount %d\n", thred, randomDev, start, end, count, maxCount)
			// 随机一次生成 【length】个2023年数据，并批量插入到时序数据库内
			timestamp, _ := randomTimestampInRange("20230101 00:00:00", "20240101 00:00:00")
			BatchInsertTestDataToDB(length, timestamp, randomDev)
			break
		}
	}

}

// terminal_sn_1

// generateRandomString 生成一个1到10000之间的随机数，并将其转换为字符串
func generateRandomString() string {
	// 创建一个新的随机数生成器，使用时间作为种子
	src := rand.NewSource(time.Now().UnixNano())
	rng := rand.New(src)

	// 生成1到10000之间的随机数
	randomNumber := rng.Intn(10000) + 1

	// 将数字转换为字符串
	//randomString := strconv.Itoa(randomNumber)
	sprintf := fmt.Sprintf("terminal_sn_%d", randomNumber)
	return sprintf
}

func randomTimestampInRange(startStr, endStr string) (int64, error) {
	// 解析字符串为 time.Time 对象
	start, err := time.Parse("20060102 15:04:05", startStr)
	if err != nil {
		return 0, err
	}
	end, err := time.Parse("20060102 15:04:05", endStr)
	if err != nil {
		return 0, err
	}

	// 计算时间差（秒）
	delta := end.Unix() - start.Unix()
	if delta < 0 {
		return 0, fmt.Errorf("end date must be later than start date")
	}

	// 生成随机种子
	rand.Seed(time.Now().UnixNano())

	// 生成随机时间戳
	randomTimestamp := start.Unix() + rand.Int63n(delta+1) // 加1以包括结束时间点

	return randomTimestamp, nil
}
